knitr::opts_chunk$set(echo = TRUE)
rm(list = ls())
#install.packages("ona", repos = c("https://cran.qe-libs.org", "https://cran.rstudio.org")) # only run once
#install.packages("tma", repos = c("https://cran.qe-libs.org", "https://cran.rstudio.org")) # only run once
most recent data Ayano shared
data <- read.csv("~/Rprojects/ayano/PES_010v6(selected).csv")
units <- c("Speaker", "Role", "TimePhase")
codes_1 <- c("Functions", "Aesthetics", "User", "Vision", "Prototyping") # design actions codes
codes_2 <- c("CA", "ALoK", "CSU", "GCA", "Projective","Regulative","Relational") # shared epistemic agency codes
hoo_rules <- conversation_rules(
(TimePhase %in% UNIT$TimePhase & Role %in% UNIT$Role)
)
notes: accum_1 and set_1 are for design action codes; accum_2 and
set_2 are for shared epistemic agency codes
accum_1 <-
contexts(data,
units_by = units,
hoo_rules = hoo_rules) %>%
accumulate_contexts(codes = codes_1,
decay.function = decay(simple_window, window_size = 4),
return.ena.set = FALSE, norm.by = NULL)
Note: Not doing means rotation so I can compare everything in the
same space
set_1 <-
# model(accum_1,
# rotate.using = "mean",
# rotation.params =
# list(engineers=accum_1$meta.data$Role=="Engineer",
# servicedesigners=accum_1$meta.data$Role=="ServiceDesigner"))
model(accum_1)
set_1 <-
# model(accum_1,
# rotate.using = "mean",
# rotation.params =
# list(engineers=accum_1$meta.data$Role=="Engineer",
# servicedesigners=accum_1$meta.data$Role=="ServiceDesigner"))
model(accum_1)
set_2 <-
# model(accum_2,
# rotate.using = "mean",
# rotation.params =
# list(engineers=accum_2$meta.data$Role=="Engineer",
# servicedesigners=accum_2$meta.data$Role=="ServiceDesigner"))
model(accum_2)
global visual parameter (let’s make sure all the plots use the same
level of multiplier)
set_2 <-
# model(accum_2,
# rotate.using = "mean",
# rotation.params =
# list(engineers=accum_2$meta.data$Role=="Engineer",
# servicedesigners=accum_2$meta.data$Role=="ServiceDesigner"))
model(accum_2)
Model 1: design action codes
Plot 1a: Overall Group Comparisons
traces = c(2:10)
plot(set_1, title = "Groups") |>
units(
points= set_1$points$Role$ProductDesigner,
point_position_multiplier = point_position_multiplier,
points_color = c("red"),
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points= set_1$points$Role$Engineer,
point_position_multiplier = point_position_multiplier,
points_color = c("blue"),
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points= set_1$points$Role$ServiceDesigner,
point_position_multiplier = point_position_multiplier,
points_color = c("green"),
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
nodes(node_size_multiplier = 0.3,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("black"))|>
plotly::layout(showlegend = TRUE, legend = list(x = 100, y = 0.9)) |>
plotly::style(name = "Product Designer", traces = traces[1]) |>
plotly::style(name = "Engineer", traces = traces[2]) |>
plotly::style(name = "Service Designer", traces = traces[3])
NA
Plot 1b: Group subtractions
prod_pts = set_1$points$Role$ProductDesigner
eng_pts = set_1$points$Role$Engineer
serv_pts = set_1$points$Role$ServiceDesigner
prod_mean_net = set_1$line.weights %>% dplyr::filter(Role == "ProductDesigner") %>% colMeans()
eng_mean_net = set_1$line.weights %>% dplyr::filter(Role == "Engineer") %>% colMeans()
serv_mean_net = set_1$line.weights %>% dplyr::filter(Role == "ServiceDesigner") %>% colMeans()
plot(set_1, title = "Product Designer vs Engineer") |>
units(
points = prod_pts,
points_color = "red",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points = eng_pts,
points_color = "blue",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
edges(
weights = prod_mean_net - eng_mean_net, # optional multiplier to adjust for readability
edge_size_multiplier = edge_size_multiplier,
edge_arrow_saturation_multiplier = edge_arrow_saturation_multiplier,
node_position_multiplier = node_position_multiplier,
edge_color = c("red","blue")) |>
nodes(
node_size_multiplier = node_size_multiplier,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("red","blue"))
plot(set_1, title = "Product Designer vs ServiceDesigner") |>
units(
points = prod_pts,
points_color = "red",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points =serv_pts,
points_color = "green",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
edges(
weights = prod_mean_net - serv_mean_net, # optional multiplier to adjust for readability
edge_size_multiplier = edge_size_multiplier,
edge_arrow_saturation_multiplier = edge_arrow_saturation_multiplier,
node_position_multiplier = node_position_multiplier,
edge_color = c("red","green")) |>
nodes(
node_size_multiplier = node_size_multiplier,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("red","green"))
plot(set_1, title = "Service Designer vs Engineer") |>
units(
points = serv_pts,
points_color = "green",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points = eng_pts,
points_color = "blue",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
edges(
weights = serv_mean_net - eng_mean_net, # optional multiplier to adjust for readability
edge_size_multiplier = edge_size_multiplier,
edge_arrow_saturation_multiplier = edge_arrow_saturation_multiplier,
node_position_multiplier = node_position_multiplier,
edge_color = c("green","blue")) |>
nodes(
node_size_multiplier = node_size_multiplier,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("green","blue"))
Plot 2: All Means by phase
#get list of time phases and groups loop over or use map function
phases = unique(set_1$points$TimePhase)
groups = unique(set_1$points$Role)
col_list_2 = c("red",#phase 1
"blue", #phase 2
"green") #phase 3
traces = c(2:10)
x = plot(set_1, title = "Group Means by Phase")
count = 1
for (i in 1:length(phases)){
for (j in 1:length(groups)){
points = set_1$points %>% filter(TimePhase == phases[i], Role == groups[j])
x = x |>
units(
points = points,
point_position_multiplier = point_position_multiplier,
points_color = col_list_2[i],
show_mean = TRUE, show_points = F, with_ci = FALSE
) |>
nodes(node_size_multiplier = 0.3,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("black"))|>
plotly::layout(showlegend = TRUE, legend = list(x = 100, y = 0.9)) |>
plotly::style(name = paste0(phases[i]," - ",groups[j]), traces = traces[count])
count = count + 1
}
}
x
NA
Statistical Tests:
In these data, the observations are nested within participants, so we
need to check if this nesting has a significant effect. We do this by
constructing a confidence interval around the intraclass correlation
coefficient (https://en.wikipedia.org/wiki/Intraclass_correlation).
If the interval contains zero, nesting is not significant.
reg_dat = set_1$points %>% filter(ENA_DIRECTION == "response")
ICC::ICCest(Speaker,SVD1,reg_dat) #not significant
Warning: 'x' has been coerced to a factor
$ICC
[1] 0.05242903
$LowerCI
[1] -0.2098135
$UpperCI
[1] 0.5007296
$N
[1] 10
$k
[1] 3.272727
$varw
[1] 0.3002277
$vara
[1] 0.01661158
ICC::ICCest(Speaker,SVD2,reg_dat) #not significant
Warning: 'x' has been coerced to a factor
$ICC
[1] -0.1818112
$LowerCI
[1] -0.3333495
$UpperCI
[1] 0.1964787
$N
[1] 10
$k
[1] 3.272727
$varw
[1] 0.07137526
$vara
[1] -0.01098045
Nesting is not significant so we proceed with an OLS regression.
Below we set up two models for each dimension and test whether including
interaction effects in the analysis significantly improves the
modes.
mod_x = lm(SVD1 ~ as.factor(TimePhase) + Role, data = reg_dat)
mod_y = lm(SVD2 ~ as.factor(TimePhase) + Role, data = reg_dat)
mod_x_2 = lm(SVD1 ~ as.factor(TimePhase)*Role, data = reg_dat)
anova(mod_x,mod_x_2)
Analysis of Variance Table
Model 1: SVD1 ~ as.factor(TimePhase) + Role
Model 2: SVD1 ~ as.factor(TimePhase) * Role
Res.Df RSS Df Sum of Sq F Pr(>F)
1 28 2.6341
2 24 1.7559 4 0.87815 3.0006 0.03851 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
mod_y_2 = lm(SVD2 ~ as.factor(TimePhase)*Role, data = reg_dat)
anova(mod_y,mod_y_2)
Analysis of Variance Table
Model 1: SVD2 ~ as.factor(TimePhase) + Role
Model 2: SVD2 ~ as.factor(TimePhase) * Role
Res.Df RSS Df Sum of Sq F Pr(>F)
1 28 1.1117
2 24 0.2156 4 0.89614 24.939 3.02e-08 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Interactions are significant, so we should use the interaction
models. Let’s view those models
summary(mod_x_2)
Call:
lm(formula = SVD1 ~ as.factor(TimePhase) * Role, data = reg_dat)
Residuals:
Min 1Q Median 3Q Max
-0.85356 -0.01457 0.00790 0.08624 0.32816
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.1652 0.1352 -1.221 0.23385
as.factor(TimePhase)2 0.7013 0.2066 3.395 0.00239 **
as.factor(TimePhase)3 0.6249 0.2066 3.025 0.00585 **
RoleProductDesigner -0.5044 0.1913 -2.637 0.01443 *
RoleServiceDesigner -0.6041 0.1913 -3.158 0.00425 **
as.factor(TimePhase)2:RoleProductDesigner 0.1937 0.2815 0.688 0.49803
as.factor(TimePhase)3:RoleProductDesigner 0.6236 0.2922 2.134 0.04324 *
as.factor(TimePhase)2:RoleServiceDesigner -0.2347 0.2815 -0.834 0.41272
as.factor(TimePhase)3:RoleServiceDesigner 0.6444 0.2815 2.289 0.03117 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.2705 on 24 degrees of freedom
Multiple R-squared: 0.8261, Adjusted R-squared: 0.7681
F-statistic: 14.25 on 8 and 24 DF, p-value: 2.062e-07
summary(mod_y_2)
Call:
lm(formula = SVD2 ~ as.factor(TimePhase) * Role, data = reg_dat)
Residuals:
Min 1Q Median 3Q Max
-0.196826 -0.035322 -0.001122 0.020930 0.273378
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.17794 0.04739 -3.755 0.000977 ***
as.factor(TimePhase)2 -0.08890 0.07239 -1.228 0.231326
as.factor(TimePhase)3 0.62627 0.07239 8.651 7.68e-09 ***
RoleProductDesigner 0.24264 0.06702 3.620 0.001366 **
RoleServiceDesigner 0.29823 0.06702 4.450 0.000168 ***
as.factor(TimePhase)2:RoleProductDesigner 0.06701 0.09865 0.679 0.503477
as.factor(TimePhase)3:RoleProductDesigner -0.35748 0.10237 -3.492 0.001880 **
as.factor(TimePhase)2:RoleServiceDesigner -0.27608 0.09865 -2.799 0.009962 **
as.factor(TimePhase)3:RoleServiceDesigner -0.93799 0.09865 -9.508 1.30e-09 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.09478 on 24 degrees of freedom
Multiple R-squared: 0.89, Adjusted R-squared: 0.8534
F-statistic: 24.28 on 8 and 24 DF, p-value: 1.032e-09
Viewing interactions
emmip(mod_x_2, Role ~ TimePhase)

emmip(mod_y_2, Role ~ TimePhase)

When interactions are introduced, interpreting regression
coefficients becomes more difficult, so we calculated the marginal means
and various contrasts (i.e., comparisons between groups of interest) to
address our research questions.
RQ1 (X dimension - Design Actions): Here we want to compare the “main
effect” of Role on the x dimension—i.e., are there differences between
the roles on the X dimension when averaging over TimePhases.
emm_x1 = emmeans(mod_x_2, specs = pairwise ~ Role, weights = "proportional")
NOTE: Results may be misleading due to involvement in interactions
print(emm_x1$contrasts)
contrast estimate SE df t.ratio p.value
Engineer - ProductDesigner 0.251 0.119 24 2.116 0.1077
Engineer - ServiceDesigner 0.487 0.116 24 4.192 0.0009
ProductDesigner - ServiceDesigner 0.236 0.113 24 2.085 0.1142
Results are averaged over the levels of: TimePhase
P value adjustment: tukey method for comparing a family of 3 estimates
Only significant difference on the X is between Engineer and Service
designer. Let’s calculate the effect size (difference in standard
deviations) of that difference. We will use Cohen’s d.
cohensd = function(diff_,g1,g2){
diff_/(sqrt((sd(g1)^2 + sd(g2)^2)/2))
}
contrasts = as_tibble(emm_x1$contrasts)
diff_ = contrasts$estimate[2]
g1 = reg_dat %>% filter(Role == "Engineer") %>% select(SVD1)
g2 = reg_dat %>% filter(Role == "ServiceDesigner") %>% select(SVD1)
cohensd(diff_ = diff_,g1 = g1$SVD1,g2 = g2$SVD1)
[1] 0.9779281
RQ1 (Y dimension - Design Actions): Here we want to compare the “main
effect” of Role on the y dimension—i.e., are there differences between
the roles on the X dimension when averaging over TimePhases.
emm_y1 = emmeans(mod_y_2, specs = pairwise ~ Role, weights = "proportional")
NOTE: Results may be misleading due to involvement in interactions
print(emm_y1$contrasts)
contrast estimate SE df t.ratio p.value
Engineer - ProductDesigner -0.157 0.0415 24 -3.771 0.0026
Engineer - ServiceDesigner 0.078 0.0407 24 1.917 0.1556
ProductDesigner - ServiceDesigner 0.235 0.0397 24 5.915 <.0001
Results are averaged over the levels of: TimePhase
P value adjustment: tukey method for comparing a family of 3 estimates
Significant differences between engineer/product designer and
productdesigner/servicedesigner. Let’s get the effect sizes:
contrasts = as_tibble(emm_y1$contrasts)
diff_evp = contrasts$estimate[1]
g1 = reg_dat %>% filter(Role == "Engineer") %>% select(SVD1)
g2 = reg_dat %>% filter(Role == "ProductDesigner") %>% select(SVD1)
d_evp = cohensd(diff_ = diff_,g1 = g1$SVD1,g2 = g2$SVD1)
diff_pvs = contrasts$estimate[3]
g1 = reg_dat %>% filter(Role == "ProductDesigner") %>% select(SVD1)
g2 = reg_dat %>% filter(Role == "ServiceDesigner") %>% select(SVD1)
d_pvs = cohensd(diff_ = diff_,g1 = g1$SVD1,g2 = g2$SVD1)
d_evp
[1] 0.9137988
d_pvs
[1] 0.8072687
Marginal means - x RQ2
Here we use marginal means to test for differences between timephases
within groups and groups within timephase and
library(emmeans)
emm_x1a = emmeans(mod_x_2, specs = pairwise ~ TimePhase|Role, weights = "proportional") #timephases w/ groups
emm_x1a = as_tibble(emm_x1a$contrasts)
emm_x2 = emmeans(mod_x_2, specs = pairwise ~ Role|TimePhase, weights = "proportional") #groups within timephases
emm_x2 = as_tibble(emm_x2$contrasts)
#see here: https://cran.r-project.org/web/packages/emmeans/vignettes/interactions.html
emm_x1a %>% filter(p.value < 0.05)
emm_x2 %>% filter(p.value < 0.05)
NA
Several contrasts are significant. Let’s calculate the effect
sizes
cohensd_2 = function(diff_, sd1, sd2){
cd = diff_/(sqrt((sd1^2 + sd2^2)/2))
return(cd)
}
sds.x = reg_dat %>% group_by(Role, as.factor(TimePhase)) %>% summarise(stdev = sd(SVD1))
`summarise()` has grouped output by 'Role'. You can override using the `.groups` argument.
#timephases w/n groups
eng_t1t2 = cohensd_2(emm_x1a$estimate[1],sd1 = sds.x$stdev[1], sd2 = sds.x$stdev[2])
eng_t1t3 = cohensd_2(emm_x1a$estimate[2],sd1 = sds.x$stdev[1], sd2 = sds.x$stdev[3])
sd_t1t2 = cohensd_2(emm_x1a$estimate[3],sd1 = sds.x$stdev[4], sd2 = sds.x$stdev[5])
sd_t1t3 = cohensd_2(emm_x1a$estimate[4],sd1 = sds.x$stdev[4], sd2 = sds.x$stdev[6])
pd_t1t3 = cohensd_2(emm_x1a$estimate[5],sd1 = sds.x$stdev[7], sd2 = sds.x$stdev[9])
pd_t2t3 = cohensd_2(emm_x1a$estimate[6],sd1 = sds.x$stdev[8], sd2 = sds.x$stdev[9])
print(list(eng_t1t2,eng_t1t3,sd_t1t3,sd_t1t3,pd_t1t3,pd_t2t3))
[[1]]
[1] -2.593579
[[2]]
[1] -2.272841
[[3]]
[1] -15.86154
[[4]]
[1] -15.86154
[[5]]
[1] -12.04991
[[6]]
[1] -1.557373
Marginal means - y RQ1
library(emmeans)
emm_y1= emmeans(mod_y_2, specs = pairwise ~ Role, weights = "proportional")
#print(emm_y1$emmeans)
print(emm_y1$contrasts)
Marginal means -Y RQ2
emm_y1 = emmeans(mod_y_2, specs = pairwise ~ TimePhase|Role, weights = "proportional")
print(emm_y1$contrasts)
emm_y2 = emmeans(mod_y_2, specs = pairwise ~ Role|TimePhase, weights = "proportional")
print(emm_y2$contrasts)
Calculate eff sizes
library(psych)
Model diagnostics
#todo
library(performance)
library(see)
check_model(mod_x_2)
check_model(mod_y_2)
Plot network subtractions (replace TimePhase and Role for different
combinations)
mean1 = set_1$points %>% dplyr::filter(TimePhase == 1, Role == "Engineer") #update here
mean2 = set_1$points %>% dplyr::filter(TimePhase == 1, Role == "ServiceDesigner") #update here
mean1_net = set_1$line.weights %>% dplyr::filter(TimePhase == 1, Role == "Engineer") %>% colMeans()
mean2_net = set_1$line.weights %>% dplyr::filter(TimePhase == 1, Role == "ServiceDesigner") %>% colMeans() #update here
plot(set_1, title = "Network subtraction") |>
units(
points = mean1,
points_color = "red",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points = mean2,
points_color = "blue",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
edges(
weights = mean1_net - mean2_net, # optional multiplier to adjust for readability
edge_size_multiplier = edge_size_multiplier,
edge_arrow_saturation_multiplier = edge_arrow_saturation_multiplier,
node_position_multiplier = node_position_multiplier,
edge_color = c("red","blue")) |>
nodes(
node_size_multiplier = node_size_multiplier,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("red","blue"))
Model 2: Epistemic Agency Codes
Plot 1: Mean Network
node_size_multiplier = 0.3 # scale up or down node sizes
node_position_multiplier = 1 # zoom in or out node positions
point_position_multiplier = 1 # zoom in or out the point positions
edge_arrow_saturation_multiplier = 1.5 # adjust the chevron color lighter or darker
edge_size_multiplier = 2 # scale up or down edge sizes
plot(set_2, title = "Overall Mean--Agency") |>
units(
points= set_2$points,
point_position_multiplier = point_position_multiplier,
points_color = c("black"),
show_mean = TRUE, show_points = TRUE, with_ci = TRUE) |>
edges(
weights =set_2$line.weights,
edge_size_multiplier = edge_size_multiplier,
edge_arrow_saturation_multiplier = edge_arrow_saturation_multiplier,
node_position_multiplier = node_position_multiplier,
edge_color = c("black")) |>
nodes(
node_size_multiplier = node_size_multiplier,
node_position_multiplier = node_position_multiplier,
node_labels = TRUE, # change this to FALSE can remove node labels in case you want to add them back in a nicer font or size for your presentations or publications
self_connection_color = c("black"))
Plot 1b: Overall Group Comparisons
plot(set_2, title = "Groups") |>
units(
points= set_2$points$Role$ProductDesigner,
point_position_multiplier = point_position_multiplier,
points_color = c("red"),
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points= set_2$points$Role$Engineer,
point_position_multiplier = point_position_multiplier,
points_color = c("blue"),
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points= set_2$points$Role$ServiceDesigner,
point_position_multiplier = point_position_multiplier,
points_color = c("green"),
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
nodes(node_size_multiplier = 0.3,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("black"))|>
plotly::layout(showlegend = TRUE, legend = list(x = 100, y = 0.9)) |>
plotly::style(name = "Product Designer", traces = traces[1]) |>
plotly::style(name = "Engineer", traces = traces[2]) |>
plotly::style(name = "Service Designer", traces = traces[3])
Plot 1c: Group subtractions
prod_pts = set_2$points$Role$ProductDesigner
eng_pts = set_2$points$Role$Engineer
serv_pts = set_2$points$Role$ServiceDesigner
prod_mean_net = set_2$line.weights %>% dplyr::filter(Role == "ProductDesigner") %>% colMeans()
eng_mean_net = set_2$line.weights %>% dplyr::filter(Role == "Engineer") %>% colMeans()
serv_mean_net = set_2$line.weights %>% dplyr::filter(Role == "ServiceDesigner") %>% colMeans()
plot(set_2, title = "Product Designer vs Engineer") |>
units(
points = prod_pts,
points_color = "red",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points = eng_pts,
points_color = "blue",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
edges(
weights = prod_mean_net - eng_mean_net, # optional multiplier to adjust for readability
edge_size_multiplier = edge_size_multiplier,
edge_arrow_saturation_multiplier = edge_arrow_saturation_multiplier,
node_position_multiplier = node_position_multiplier,
edge_color = c("red","blue")) |>
nodes(
node_size_multiplier = node_size_multiplier,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("red","blue"))
plot(set_2, title = "Product Designer vs ServiceDesigner") |>
units(
points = prod_pts,
points_color = "red",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points =serv_pts,
points_color = "green",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
edges(
weights = prod_mean_net - serv_mean_net, # optional multiplier to adjust for readability
edge_size_multiplier = edge_size_multiplier,
edge_arrow_saturation_multiplier = edge_arrow_saturation_multiplier,
node_position_multiplier = node_position_multiplier,
edge_color = c("red","green")) |>
nodes(
node_size_multiplier = node_size_multiplier,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("red","green"))
plot(set_2, title = "Service Designer vs Engineer") |>
units(
points = serv_pts,
points_color = "green",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points = eng_pts,
points_color = "blue",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
edges(
weights = serv_mean_net - eng_mean_net, # optional multiplier to adjust for readability
edge_size_multiplier = 1,
edge_arrow_saturation_multiplier = edge_arrow_saturation_multiplier,
node_position_multiplier = node_position_multiplier,
edge_color = c("green","blue")) |>
nodes(
node_size_multiplier = node_size_multiplier,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("green","blue"))
Plot 2: All Means
#get list of time phases and groups loop over or use map function
phases = unique(set_2$points$TimePhase)
groups = unique(set_2$points$Role)
col_list_2 = c("red",
"blue",
"green")
traces = c(2:10)
x_agency = plot(set_2, title = "Group Means by Phase -- Agency")
count = 1
for (i in 1:length(phases)){
for (j in 1:length(groups)){
points = set_2$points %>% filter(TimePhase == phases[i], Role == groups[j])
#print(head(points))
x_agency = x_agency |>
units(
points = points,
point_position_multiplier = point_position_multiplier,
points_color = col_list_2[i],
show_mean = TRUE, show_points = F, with_ci = FALSE
) |>
nodes(node_size_multiplier = 0.3,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("black"))|>
plotly::layout(showlegend = TRUE, legend = list(x = 100, y = 0.9)) |>
plotly::style(name = paste0(phases[i]," - ",groups[j]), traces = traces[count])
count = count + 1
}
}
x_agency
Check nesting
reg_dat_agency = set_2$points %>% filter(ENA_DIRECTION == "response")
ICC::ICCest(Speaker,SVD1,reg_dat_agency) #not significant
ICC::ICCest(Speaker,SVD2,reg_dat_agency) #significant we will need to include a variable for individual in the model
mod_x_agency = lm(SVD1 ~ as.factor(TimePhase) + Role, data = reg_dat_agency)
mod_y_agency = lm(SVD2 ~ as.factor(TimePhase) + Role, data = reg_dat_agency)
summary(mod_x_agency)
summary(mod_y_agency)
check for interactions: (interactions are significant so we should
use those modes)
mod_x_agency_2 = lm(SVD1 ~ as.factor(TimePhase) + Role + as.factor(TimePhase)*Role, data = reg_dat_agency)
mod_y_agency_2 = lm(SVD2 ~ as.factor(TimePhase) + Role + as.factor(TimePhase)*Role, data = reg_dat_agency)
summary(mod_x_agency_2)
summary(mod_y_agency_2)
anova(mod_x_agency,mod_x_agency_2)
anova(mod_y_agency,mod_y_agency_2)
#Need to run mixed model for Y ##model is singular so stick with
OLS
library(lmerTest)
mod_y_agency_mixed = lmerTest::lmer(SVD2 ~ 1 + (1|Speaker) + as.factor(TimePhase)*Role ,data = reg_dat_agency)
summary(mod_y_agency_mixed)
Marginal means x - RQ1
emm_ag1 = emmeans(mod_x_agency_2, specs = pairwise ~ Role, weights = "proportional")
print(emm_ag1$emmeans)
print(emm_ag1$contrasts)
Viewing interactions
emmip(mod_x_agency_2, Role ~ TimePhase)
Marginal means - x RQ2
emm_ag1 = emmeans(mod_x_agency_2, specs = pairwise ~ TimePhase|Role, weights = "proportional")
emm_ag1$contrasts
emm_ag2 = emmeans(mod_x_agency_2, specs = pairwise ~ Role|TimePhase, weights = "proportional")
emm_ag2$contrasts
Marginal means y - RQ1
emm_ag_y1 = emmeans(mod_y_agency_2, specs = pairwise ~ Role, weights = "proportional")
print(emm_ag_y1$emmeans)
print(emm_ag_y1$contrasts)
Viewing interactions
emmip(mod_y_agency_2, Role ~ TimePhase)
Marginal means - y RQ2
emm_ag_y1 = emmeans(mod_y_agency_2, specs = pairwise ~ TimePhase|Role, weights = "proportional")
emm_ag_y1$contrasts
emm_ag_y2 = emmeans(mod_y_agency_2, specs = pairwise ~ Role|TimePhase, weights = "proportional")
emm_ag_y2$contrasts
Calculate eff sizes
#to do
Model diagnostics
check_model(mod_x_agency_2)
check_model(mod_y_agency_2)
Plot network subtractions
mean1 = set_2$points %>% dplyr::filter(TimePhase == 1, Role == "Engineer")
mean2 = set_2$points %>% dplyr::filter(TimePhase == 1, Role == "ProductDesigner")
mean1_net = set_2$line.weights %>% dplyr::filter(TimePhase == 1, Role == "Engineer") %>% colMeans()
mean2_net = set_2$line.weights %>% dplyr::filter(TimePhase == 1, Role == "ProductDesigner") %>% colMeans()
plot(set_2, title = "Network subtraction") |>
units(
points = mean1,
points_color = "red",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
units(
points = mean2,
points_color = "blue",
show_mean = TRUE, show_points = FALSE, with_ci = TRUE) |>
edges(
weights = mean1_net - mean2_net, # optional multiplier to adjust for readability
edge_size_multiplier = edge_size_multiplier,
edge_arrow_saturation_multiplier = edge_arrow_saturation_multiplier,
node_position_multiplier = node_position_multiplier,
edge_color = c("red","blue")) |>
nodes(
node_size_multiplier = node_size_multiplier,
node_position_multiplier = node_position_multiplier,
self_connection_color = c("red","blue"))
LS0tCnRpdGxlOiAiSkxBLU9OQS0yMDIzIgphdXRob3I6ICJaYWNoICYgWXVhbnJ1IgpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCmVkaXRvcl9vcHRpb25zOgogIG1hcmtkb3duOgogICAgd3JhcDogc2VudGVuY2UKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1UUlVFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKYGBge3J9CnJtKGxpc3QgPSBscygpKQpgYGAKCmBgYHtyfQojaW5zdGFsbC5wYWNrYWdlcygib25hIiwgcmVwb3MgPSBjKCJodHRwczovL2NyYW4ucWUtbGlicy5vcmciLCAiaHR0cHM6Ly9jcmFuLnJzdHVkaW8ub3JnIikpICMgb25seSBydW4gb25jZQojaW5zdGFsbC5wYWNrYWdlcygidG1hIiwgcmVwb3MgPSBjKCJodHRwczovL2NyYW4ucWUtbGlicy5vcmciLCAiaHR0cHM6Ly9jcmFuLnJzdHVkaW8ub3JnIikpICMgb25seSBydW4gb25jZQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkob25hKQpsaWJyYXJ5KHRtYSkKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZW1tZWFucykKbGlicmFyeShwZXJmb3JtYW5jZSkKYGBgCgptb3N0IHJlY2VudCBkYXRhIEF5YW5vIHNoYXJlZApgYGB7cn0KZGF0YSA8LSByZWFkLmNzdigifi9ScHJvamVjdHMvYXlhbm8vUEVTXzAxMHY2KHNlbGVjdGVkKS5jc3YiKQpgYGAKCmBgYHtyfQp1bml0cyA8LSBjKCJTcGVha2VyIiwgIlJvbGUiLCAiVGltZVBoYXNlIikKCmNvZGVzXzEgPC0gYygiRnVuY3Rpb25zIiwgIkFlc3RoZXRpY3MiLCAiVXNlciIsICJWaXNpb24iLCAiUHJvdG90eXBpbmciKSAjIGRlc2lnbiBhY3Rpb25zIGNvZGVzCmNvZGVzXzIgPC0gYygiQ0EiLCAiQUxvSyIsICJDU1UiLCAiR0NBIiwgIlByb2plY3RpdmUiLCJSZWd1bGF0aXZlIiwiUmVsYXRpb25hbCIpICMgc2hhcmVkIGVwaXN0ZW1pYyBhZ2VuY3kgY29kZXMKCmhvb19ydWxlcyA8LSBjb252ZXJzYXRpb25fcnVsZXMoCiAgKFRpbWVQaGFzZSAlaW4lIFVOSVQkVGltZVBoYXNlICYgUm9sZSAlaW4lIFVOSVQkUm9sZSkKKQpgYGAKCm5vdGVzOiBhY2N1bV8xIGFuZCBzZXRfMSBhcmUgZm9yIGRlc2lnbiBhY3Rpb24gY29kZXM7IGFjY3VtXzIgYW5kIHNldF8yIGFyZSBmb3Igc2hhcmVkIGVwaXN0ZW1pYyBhZ2VuY3kgY29kZXMKCmBgYHtyfQphY2N1bV8xIDwtCiAgY29udGV4dHMoZGF0YSwgCiAgICAgICAgICAgdW5pdHNfYnkgPSB1bml0cywgCiAgICAgICAgICAgaG9vX3J1bGVzID0gaG9vX3J1bGVzKSAlPiUKICBhY2N1bXVsYXRlX2NvbnRleHRzKGNvZGVzID0gY29kZXNfMSwgCiAgICAgICAgICAgICAgICAgICAgICBkZWNheS5mdW5jdGlvbiA9IGRlY2F5KHNpbXBsZV93aW5kb3csIHdpbmRvd19zaXplID0gNCksCiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4uZW5hLnNldCA9IEZBTFNFLCBub3JtLmJ5ID0gTlVMTCkKYGBgCgpOb3RlOiBOb3QgZG9pbmcgbWVhbnMgcm90YXRpb24gc28gSSBjYW4gY29tcGFyZSBldmVyeXRoaW5nIGluIHRoZSBzYW1lIHNwYWNlCgpgYGB7cn0Kc2V0XzEgPC0KICAjIG1vZGVsKGFjY3VtXzEsCiAgIyAgICAgICByb3RhdGUudXNpbmcgPSAibWVhbiIsCiAgIyAgICAgICByb3RhdGlvbi5wYXJhbXMgPSAKICAjICAgICAgICAgbGlzdChlbmdpbmVlcnM9YWNjdW1fMSRtZXRhLmRhdGEkUm9sZT09IkVuZ2luZWVyIiwKICAjICAgICAgICAgICAgICBzZXJ2aWNlZGVzaWduZXJzPWFjY3VtXzEkbWV0YS5kYXRhJFJvbGU9PSJTZXJ2aWNlRGVzaWduZXIiKSkKICAKICBtb2RlbChhY2N1bV8xKQpgYGAKCmBgYHtyfQphY2N1bV8yIDwtCiAgY29udGV4dHMoZGF0YSwgCiAgICAgICAgICAgdW5pdHNfYnkgPSB1bml0cywgCiAgICAgICAgICAgaG9vX3J1bGVzID0gaG9vX3J1bGVzKSAlPiUKICBhY2N1bXVsYXRlX2NvbnRleHRzKGNvZGVzID0gY29kZXNfMiwgCiAgICAgICAgICAgICAgICAgICAgICBkZWNheS5mdW5jdGlvbiA9IGRlY2F5KHNpbXBsZV93aW5kb3csIHdpbmRvd19zaXplID0gNCksCiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4uZW5hLnNldCA9IEZBTFNFLCBub3JtLmJ5ID0gTlVMTCkKYGBgCgpgYGB7cn0Kc2V0XzIgPC0KICAjIG1vZGVsKGFjY3VtXzIsCiAgIyAgICAgICByb3RhdGUudXNpbmcgPSAibWVhbiIsCiAgIyAgICAgICByb3RhdGlvbi5wYXJhbXMgPSAKICAjICAgICAgICAgbGlzdChlbmdpbmVlcnM9YWNjdW1fMiRtZXRhLmRhdGEkUm9sZT09IkVuZ2luZWVyIiwKICAjICAgICAgICAgICAgICBzZXJ2aWNlZGVzaWduZXJzPWFjY3VtXzIkbWV0YS5kYXRhJFJvbGU9PSJTZXJ2aWNlRGVzaWduZXIiKSkKICAKICBtb2RlbChhY2N1bV8yKQpgYGAKCmdsb2JhbCB2aXN1YWwgcGFyYW1ldGVyIChsZXQncyBtYWtlIHN1cmUgYWxsIHRoZSBwbG90cyB1c2UgdGhlIHNhbWUgbGV2ZWwgb2YgbXVsdGlwbGllcikKYGBge3J9Cm5vZGVfc2l6ZV9tdWx0aXBsaWVyID0gMC4zICMgc2NhbGUgdXAgb3IgZG93biBub2RlIHNpemVzCm5vZGVfcG9zaXRpb25fbXVsdGlwbGllciA9IDEgIyB6b29tIGluIG9yIG91dCBub2RlIHBvc2l0aW9ucwpwb2ludF9wb3NpdGlvbl9tdWx0aXBsaWVyID0gMSAjIHpvb20gaW4gb3Igb3V0IHRoZSBwb2ludCBwb3NpdGlvbnMKZWRnZV9hcnJvd19zYXR1cmF0aW9uX211bHRpcGxpZXIgPSAxLjUgIyBhZGp1c3QgdGhlIGNoZXZyb24gY29sb3IgbGlnaHRlciBvciBkYXJrZXIKZWRnZV9zaXplX211bHRpcGxpZXIgPSAxICMgc2NhbGUgdXAgb3IgZG93biBlZGdlIHNpemVzCmBgYAoKTW9kZWwgMTogZGVzaWduIGFjdGlvbiBjb2RlcwoKUGxvdCAxYTogT3ZlcmFsbCBHcm91cCBDb21wYXJpc29ucwpgYGB7cn0KdHJhY2VzID0gYygyOjEwKQpwbG90KHNldF8xLCB0aXRsZSA9ICJHcm91cHMiKSB8PgogIHVuaXRzKAogICAgcG9pbnRzPSBzZXRfMSRwb2ludHMkUm9sZSRQcm9kdWN0RGVzaWduZXIsIAogICAgcG9pbnRfcG9zaXRpb25fbXVsdGlwbGllciA9IHBvaW50X3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBwb2ludHNfY29sb3IgPSBjKCJyZWQiKSwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogICB1bml0cygKICAgIHBvaW50cz0gc2V0XzEkcG9pbnRzJFJvbGUkRW5naW5lZXIsIAogICAgcG9pbnRfcG9zaXRpb25fbXVsdGlwbGllciA9IHBvaW50X3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBwb2ludHNfY29sb3IgPSBjKCJibHVlIiksCiAgICBzaG93X21lYW4gPSBUUlVFLCBzaG93X3BvaW50cyA9IEZBTFNFLCB3aXRoX2NpID0gVFJVRSkgfD4KICAgdW5pdHMoCiAgICBwb2ludHM9IHNldF8xJHBvaW50cyRSb2xlJFNlcnZpY2VEZXNpZ25lciwgCiAgICBwb2ludF9wb3NpdGlvbl9tdWx0aXBsaWVyID0gcG9pbnRfcG9zaXRpb25fbXVsdGlwbGllciwKICAgIHBvaW50c19jb2xvciA9IGMoImdyZWVuIiksCiAgICBzaG93X21lYW4gPSBUUlVFLCBzaG93X3BvaW50cyA9IEZBTFNFLCB3aXRoX2NpID0gVFJVRSkgfD4KICBub2Rlcyhub2RlX3NpemVfbXVsdGlwbGllciA9IDAuMywKICAgICAgICAgICAgbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyID0gbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyLAogICAgICAgICAgICBzZWxmX2Nvbm5lY3Rpb25fY29sb3IgPSBjKCJibGFjayIpKXw+CiAgICAgIHBsb3RseTo6bGF5b3V0KHNob3dsZWdlbmQgPSBUUlVFLCBsZWdlbmQgPSBsaXN0KHggPSAxMDAsIHkgPSAwLjkpKSB8PgogICAgICBwbG90bHk6OnN0eWxlKG5hbWUgPSAiUHJvZHVjdCBEZXNpZ25lciIsIHRyYWNlcyA9IHRyYWNlc1sxXSkgfD4KICAgICAgcGxvdGx5OjpzdHlsZShuYW1lID0gIkVuZ2luZWVyIiwgdHJhY2VzID0gdHJhY2VzWzJdKSB8PgogICAgICBwbG90bHk6OnN0eWxlKG5hbWUgPSAiU2VydmljZSBEZXNpZ25lciIsIHRyYWNlcyA9IHRyYWNlc1szXSkKICAKYGBgClBsb3QgMWI6IEdyb3VwIHN1YnRyYWN0aW9ucwpgYGB7cn0KcHJvZF9wdHMgPSBzZXRfMSRwb2ludHMkUm9sZSRQcm9kdWN0RGVzaWduZXIgCmVuZ19wdHMgPSBzZXRfMSRwb2ludHMkUm9sZSRFbmdpbmVlcgpzZXJ2X3B0cyA9IHNldF8xJHBvaW50cyRSb2xlJFNlcnZpY2VEZXNpZ25lcgoKcHJvZF9tZWFuX25ldCA9IHNldF8xJGxpbmUud2VpZ2h0cyAlPiUgZHBseXI6OmZpbHRlcihSb2xlID09ICJQcm9kdWN0RGVzaWduZXIiKSAlPiUgY29sTWVhbnMoKQplbmdfbWVhbl9uZXQgPSBzZXRfMSRsaW5lLndlaWdodHMgJT4lIGRwbHlyOjpmaWx0ZXIoUm9sZSA9PSAiRW5naW5lZXIiKSAlPiUgY29sTWVhbnMoKQpzZXJ2X21lYW5fbmV0ID0gc2V0XzEkbGluZS53ZWlnaHRzICU+JSBkcGx5cjo6ZmlsdGVyKFJvbGUgPT0gIlNlcnZpY2VEZXNpZ25lciIpICU+JSBjb2xNZWFucygpCgpwbG90KHNldF8xLCB0aXRsZSA9ICJQcm9kdWN0IERlc2lnbmVyIHZzIEVuZ2luZWVyIikgfD4KICB1bml0cygKICAgIHBvaW50cyA9IHByb2RfcHRzLCAKICAgIHBvaW50c19jb2xvciA9ICJyZWQiLAogICAgc2hvd19tZWFuID0gVFJVRSwgc2hvd19wb2ludHMgPSBGQUxTRSwgd2l0aF9jaSA9IFRSVUUpIHw+CiAgdW5pdHMoCiAgICBwb2ludHMgPSBlbmdfcHRzLCAKICAgIHBvaW50c19jb2xvciA9ICJibHVlIiwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogIGVkZ2VzKAogICAgd2VpZ2h0cyA9IHByb2RfbWVhbl9uZXQgLSBlbmdfbWVhbl9uZXQsICMgb3B0aW9uYWwgbXVsdGlwbGllciB0byBhZGp1c3QgZm9yIHJlYWRhYmlsaXR5CiAgICBlZGdlX3NpemVfbXVsdGlwbGllciA9IGVkZ2Vfc2l6ZV9tdWx0aXBsaWVyLAogICAgZWRnZV9hcnJvd19zYXR1cmF0aW9uX211bHRpcGxpZXIgPSBlZGdlX2Fycm93X3NhdHVyYXRpb25fbXVsdGlwbGllciwKICAgIG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciA9IG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciwKICAgIGVkZ2VfY29sb3IgPSBjKCJyZWQiLCJibHVlIikpIHw+CiAgbm9kZXMoCiAgICBub2RlX3NpemVfbXVsdGlwbGllciA9IG5vZGVfc2l6ZV9tdWx0aXBsaWVyLAogICAgbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyID0gbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyLAogICAgc2VsZl9jb25uZWN0aW9uX2NvbG9yID0gYygicmVkIiwiYmx1ZSIpKQoKcGxvdChzZXRfMSwgdGl0bGUgPSAiUHJvZHVjdCBEZXNpZ25lciB2cyBTZXJ2aWNlRGVzaWduZXIiKSB8PgogIHVuaXRzKAogICAgcG9pbnRzID0gcHJvZF9wdHMsIAogICAgcG9pbnRzX2NvbG9yID0gInJlZCIsCiAgICBzaG93X21lYW4gPSBUUlVFLCBzaG93X3BvaW50cyA9IEZBTFNFLCB3aXRoX2NpID0gVFJVRSkgfD4KICB1bml0cygKICAgIHBvaW50cyA9c2Vydl9wdHMsIAogICAgcG9pbnRzX2NvbG9yID0gImdyZWVuIiwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogIGVkZ2VzKAogICAgd2VpZ2h0cyA9IHByb2RfbWVhbl9uZXQgLSBzZXJ2X21lYW5fbmV0LCAjIG9wdGlvbmFsIG11bHRpcGxpZXIgdG8gYWRqdXN0IGZvciByZWFkYWJpbGl0eQogICAgZWRnZV9zaXplX211bHRpcGxpZXIgPSBlZGdlX3NpemVfbXVsdGlwbGllciwKICAgIGVkZ2VfYXJyb3dfc2F0dXJhdGlvbl9tdWx0aXBsaWVyID0gZWRnZV9hcnJvd19zYXR1cmF0aW9uX211bHRpcGxpZXIsCiAgICBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIgPSBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBlZGdlX2NvbG9yID0gYygicmVkIiwiZ3JlZW4iKSkgfD4KICBub2RlcygKICAgIG5vZGVfc2l6ZV9tdWx0aXBsaWVyID0gbm9kZV9zaXplX211bHRpcGxpZXIsCiAgICBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIgPSBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBzZWxmX2Nvbm5lY3Rpb25fY29sb3IgPSBjKCJyZWQiLCJncmVlbiIpKQoKcGxvdChzZXRfMSwgdGl0bGUgPSAiU2VydmljZSBEZXNpZ25lciB2cyBFbmdpbmVlciIpIHw+CiAgdW5pdHMoCiAgICBwb2ludHMgPSBzZXJ2X3B0cywgCiAgICBwb2ludHNfY29sb3IgPSAiZ3JlZW4iLAogICAgc2hvd19tZWFuID0gVFJVRSwgc2hvd19wb2ludHMgPSBGQUxTRSwgd2l0aF9jaSA9IFRSVUUpIHw+CiAgdW5pdHMoCiAgICBwb2ludHMgPSBlbmdfcHRzLCAKICAgIHBvaW50c19jb2xvciA9ICJibHVlIiwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogIGVkZ2VzKAogICAgd2VpZ2h0cyA9IHNlcnZfbWVhbl9uZXQgLSBlbmdfbWVhbl9uZXQsICMgb3B0aW9uYWwgbXVsdGlwbGllciB0byBhZGp1c3QgZm9yIHJlYWRhYmlsaXR5CiAgICBlZGdlX3NpemVfbXVsdGlwbGllciA9IGVkZ2Vfc2l6ZV9tdWx0aXBsaWVyLAogICAgZWRnZV9hcnJvd19zYXR1cmF0aW9uX211bHRpcGxpZXIgPSBlZGdlX2Fycm93X3NhdHVyYXRpb25fbXVsdGlwbGllciwKICAgIG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciA9IG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciwKICAgIGVkZ2VfY29sb3IgPSBjKCJncmVlbiIsImJsdWUiKSkgfD4KICBub2RlcygKICAgIG5vZGVfc2l6ZV9tdWx0aXBsaWVyID0gbm9kZV9zaXplX211bHRpcGxpZXIsCiAgICBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIgPSBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBzZWxmX2Nvbm5lY3Rpb25fY29sb3IgPSBjKCJncmVlbiIsImJsdWUiKSkKYGBgClBsb3QgMjogQWxsIE1lYW5zIGJ5IHBoYXNlCmBgYHtyfQoKI2dldCBsaXN0IG9mIHRpbWUgcGhhc2VzIGFuZCBncm91cHMgbG9vcCBvdmVyIG9yIHVzZSBtYXAgZnVuY3Rpb24KCnBoYXNlcyA9IHVuaXF1ZShzZXRfMSRwb2ludHMkVGltZVBoYXNlKQoKZ3JvdXBzID0gdW5pcXVlKHNldF8xJHBvaW50cyRSb2xlKQoKY29sX2xpc3RfMiA9IGMoInJlZCIsI3BoYXNlIDEKICAgICAgICAgICAgICAiYmx1ZSIsICNwaGFzZSAyCiAgICAgICAgICAgICAgImdyZWVuIikgI3BoYXNlIDMKCnRyYWNlcyA9IGMoMjoxMCkKCnggPSBwbG90KHNldF8xLCB0aXRsZSA9ICJHcm91cCBNZWFucyBieSBQaGFzZSIpCmNvdW50ID0gMQpmb3IgKGkgaW4gMTpsZW5ndGgocGhhc2VzKSl7CiAgZm9yIChqIGluIDE6bGVuZ3RoKGdyb3VwcykpewogICAgcG9pbnRzID0gc2V0XzEkcG9pbnRzICU+JSBmaWx0ZXIoVGltZVBoYXNlID09IHBoYXNlc1tpXSwgUm9sZSA9PSBncm91cHNbal0pCiAgICB4ID0geCB8PgogICAgICB1bml0cygKICAgICAgICBwb2ludHMgPSBwb2ludHMsCiAgICAgICAgcG9pbnRfcG9zaXRpb25fbXVsdGlwbGllciA9IHBvaW50X3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICAgICAgcG9pbnRzX2NvbG9yID0gY29sX2xpc3RfMltpXSwKICAgICAgICBzaG93X21lYW4gPSBUUlVFLCBzaG93X3BvaW50cyA9IEYsIHdpdGhfY2kgPSBGQUxTRQogICAgICAgICkgfD4KICAgICAgbm9kZXMobm9kZV9zaXplX211bHRpcGxpZXIgPSAwLjMsCiAgICAgICAgICAgIG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciA9IG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciwKICAgICAgICAgICAgc2VsZl9jb25uZWN0aW9uX2NvbG9yID0gYygiYmxhY2siKSl8PgogICAgICBwbG90bHk6OmxheW91dChzaG93bGVnZW5kID0gVFJVRSwgbGVnZW5kID0gbGlzdCh4ID0gMTAwLCB5ID0gMC45KSkgfD4KICAgICAgcGxvdGx5OjpzdHlsZShuYW1lID0gcGFzdGUwKHBoYXNlc1tpXSwiIC0gIixncm91cHNbal0pLCB0cmFjZXMgPSB0cmFjZXNbY291bnRdKQogICAgY291bnQgPSBjb3VudCArIDEKICB9Cn0KCngKCmBgYAoKU3RhdGlzdGljYWwgVGVzdHM6CgpJbiB0aGVzZSBkYXRhLCB0aGUgb2JzZXJ2YXRpb25zIGFyZSBuZXN0ZWQgd2l0aGluIHBhcnRpY2lwYW50cywgc28gd2UgbmVlZCB0byBjaGVjayBpZiB0aGlzIG5lc3RpbmcgCmhhcyBhIHNpZ25pZmljYW50IGVmZmVjdC4gV2UgZG8gdGhpcyBieSBjb25zdHJ1Y3RpbmcgYSBjb25maWRlbmNlIGludGVydmFsCmFyb3VuZCB0aGUgaW50cmFjbGFzcyBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW50cmFjbGFzc19jb3JyZWxhdGlvbikuIElmIHRoZSBpbnRlcnZhbCBjb250YWlucyB6ZXJvLCBuZXN0aW5nIGlzIG5vdCBzaWduaWZpY2FudC4KCmBgYHtyfQpyZWdfZGF0ID0gc2V0XzEkcG9pbnRzICU+JSBmaWx0ZXIoRU5BX0RJUkVDVElPTiA9PSAicmVzcG9uc2UiKQoKSUNDOjpJQ0Nlc3QoU3BlYWtlcixTVkQxLHJlZ19kYXQpICNub3Qgc2lnbmlmaWNhbnQKCklDQzo6SUNDZXN0KFNwZWFrZXIsU1ZEMixyZWdfZGF0KSAjbm90IHNpZ25pZmljYW50CgoKYGBgCgpOZXN0aW5nIGlzIG5vdCBzaWduaWZpY2FudCBzbyB3ZSBwcm9jZWVkIHdpdGggYW4gT0xTIHJlZ3Jlc3Npb24uIEJlbG93IHdlIHNldCB1cCB0d28gbW9kZWxzIGZvciBlYWNoIGRpbWVuc2lvbiBhbmQgdGVzdCB3aGV0aGVyIGluY2x1ZGluZyBpbnRlcmFjdGlvbiBlZmZlY3RzIGluIHRoZSBhbmFseXNpcyBzaWduaWZpY2FudGx5IGltcHJvdmVzIHRoZSBtb2Rlcy4KCmBgYHtyfQptb2RfeCA9IGxtKFNWRDEgfiBhcy5mYWN0b3IoVGltZVBoYXNlKSArIFJvbGUsIGRhdGEgPSByZWdfZGF0KQptb2RfeSA9IGxtKFNWRDIgfiBhcy5mYWN0b3IoVGltZVBoYXNlKSArIFJvbGUsIGRhdGEgPSByZWdfZGF0KQoKbW9kX3hfMiA9IGxtKFNWRDEgfiBhcy5mYWN0b3IoVGltZVBoYXNlKSpSb2xlLCBkYXRhID0gcmVnX2RhdCkKYW5vdmEobW9kX3gsbW9kX3hfMikKCm1vZF95XzIgPSBsbShTVkQyIH4gYXMuZmFjdG9yKFRpbWVQaGFzZSkqUm9sZSwgZGF0YSA9IHJlZ19kYXQpCmFub3ZhKG1vZF95LG1vZF95XzIpCgpgYGAKSW50ZXJhY3Rpb25zIGFyZSBzaWduaWZpY2FudCwgc28gd2Ugc2hvdWxkIHVzZSB0aGUgaW50ZXJhY3Rpb24gbW9kZWxzLiBMZXQncyB2aWV3IHRob3NlIG1vZGVscwoKYGBge3J9CnN1bW1hcnkobW9kX3hfMikKc3VtbWFyeShtb2RfeV8yKQpgYGAKVmlld2luZyBpbnRlcmFjdGlvbnMKYGBge3J9CmVtbWlwKG1vZF94XzIsIFJvbGUgfiBUaW1lUGhhc2UpCmVtbWlwKG1vZF95XzIsIFJvbGUgfiBUaW1lUGhhc2UpCmBgYApXaGVuIGludGVyYWN0aW9ucyBhcmUgaW50cm9kdWNlZCwgaW50ZXJwcmV0aW5nIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzIGJlY29tZXMgbW9yZSAKZGlmZmljdWx0LCBzbyB3ZSBjYWxjdWxhdGVkIHRoZSBtYXJnaW5hbCBtZWFucyBhbmQgdmFyaW91cyBjb250cmFzdHMgKGkuZS4sIGNvbXBhcmlzb25zIGJldHdlZW4gZ3JvdXBzIG9mIGludGVyZXN0KSB0byBhZGRyZXNzIG91ciByZXNlYXJjaCBxdWVzdGlvbnMuCgpSUTEgKFggZGltZW5zaW9uIC0gRGVzaWduIEFjdGlvbnMpOiBIZXJlIHdlIHdhbnQgdG8gY29tcGFyZSB0aGUgIm1haW4gZWZmZWN0IiBvZiBSb2xlIG9uIHRoZSB4IGRpbWVuc2lvbi0tLWkuZS4sIGFyZSB0aGVyZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSByb2xlcyBvbiB0aGUgWCBkaW1lbnNpb24gd2hlbiBhdmVyYWdpbmcgb3ZlciBUaW1lUGhhc2VzLgoKYGBge3J9CmVtbV94MSA9IGVtbWVhbnMobW9kX3hfMiwgc3BlY3MgPSBwYWlyd2lzZSB+IFJvbGUsIHdlaWdodHMgPSAicHJvcG9ydGlvbmFsIikKcHJpbnQoZW1tX3gxJGNvbnRyYXN0cykKYGBgCk9ubHkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBvbiB0aGUgWCBpcyBiZXR3ZWVuIEVuZ2luZWVyIGFuZCBTZXJ2aWNlIGRlc2lnbmVyLiBMZXQncyBjYWxjdWxhdGUgdGhlIGVmZmVjdCBzaXplIChkaWZmZXJlbmNlIGluIHN0YW5kYXJkIGRldmlhdGlvbnMpIG9mIHRoYXQgZGlmZmVyZW5jZS4gV2Ugd2lsbCB1c2UgQ29oZW4ncyBkLgoKYGBge3J9CmNvaGVuc2QgPSBmdW5jdGlvbihkaWZmXyxnMSxnMil7CiAgZGlmZl8vKHNxcnQoKHNkKGcxKV4yICsgc2QoZzIpXjIpLzIpKQp9Cgpjb250cmFzdHMgPSBhc190aWJibGUoZW1tX3gxJGNvbnRyYXN0cykKZGlmZl8gPSBjb250cmFzdHMkZXN0aW1hdGVbMl0KZzEgPSByZWdfZGF0ICU+JSBmaWx0ZXIoUm9sZSA9PSAiRW5naW5lZXIiKSAlPiUgc2VsZWN0KFNWRDEpCmcyID0gcmVnX2RhdCAlPiUgZmlsdGVyKFJvbGUgPT0gIlNlcnZpY2VEZXNpZ25lciIpICU+JSBzZWxlY3QoU1ZEMSkKCmNvaGVuc2QoZGlmZl8gPSBkaWZmXyxnMSA9IGcxJFNWRDEsZzIgPSBnMiRTVkQxKQoKYGBgCgpSUTEgKFkgZGltZW5zaW9uIC0gRGVzaWduIEFjdGlvbnMpOiBIZXJlIHdlIHdhbnQgdG8gY29tcGFyZSB0aGUgIm1haW4gZWZmZWN0IiBvZiBSb2xlIG9uIHRoZSB5IGRpbWVuc2lvbi0tLWkuZS4sIGFyZSB0aGVyZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSByb2xlcyBvbiB0aGUgWCBkaW1lbnNpb24gd2hlbiBhdmVyYWdpbmcgb3ZlciBUaW1lUGhhc2VzLgoKYGBge3J9CmVtbV95MSA9IGVtbWVhbnMobW9kX3lfMiwgc3BlY3MgPSBwYWlyd2lzZSB+IFJvbGUsIHdlaWdodHMgPSAicHJvcG9ydGlvbmFsIikKcHJpbnQoZW1tX3kxJGNvbnRyYXN0cykKYGBgClNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGJldHdlZW4gZW5naW5lZXIvcHJvZHVjdCBkZXNpZ25lciBhbmQgcHJvZHVjdGRlc2lnbmVyL3NlcnZpY2VkZXNpZ25lci4gTGV0J3MgZ2V0IHRoZSBlZmZlY3Qgc2l6ZXM6CgpgYGB7cn0KY29udHJhc3RzID0gYXNfdGliYmxlKGVtbV95MSRjb250cmFzdHMpCgpkaWZmX2V2cCA9IGNvbnRyYXN0cyRlc3RpbWF0ZVsxXQpnMSA9IHJlZ19kYXQgJT4lIGZpbHRlcihSb2xlID09ICJFbmdpbmVlciIpICU+JSBzZWxlY3QoU1ZEMSkKZzIgPSByZWdfZGF0ICU+JSBmaWx0ZXIoUm9sZSA9PSAiUHJvZHVjdERlc2lnbmVyIikgJT4lIHNlbGVjdChTVkQxKQoKZF9ldnAgPSBjb2hlbnNkKGRpZmZfID0gZGlmZl8sZzEgPSBnMSRTVkQxLGcyID0gZzIkU1ZEMSkKCmRpZmZfcHZzID0gY29udHJhc3RzJGVzdGltYXRlWzNdCmcxID0gcmVnX2RhdCAlPiUgZmlsdGVyKFJvbGUgPT0gIlByb2R1Y3REZXNpZ25lciIpICU+JSBzZWxlY3QoU1ZEMSkKZzIgPSByZWdfZGF0ICU+JSBmaWx0ZXIoUm9sZSA9PSAiU2VydmljZURlc2lnbmVyIikgJT4lIHNlbGVjdChTVkQxKQoKZF9wdnMgPSBjb2hlbnNkKGRpZmZfID0gZGlmZl8sZzEgPSBnMSRTVkQxLGcyID0gZzIkU1ZEMSkKCmRfZXZwCmRfcHZzCmBgYAoKTWFyZ2luYWwgbWVhbnMgLSB4IFJRMgoKCkhlcmUgd2UgdXNlIG1hcmdpbmFsIG1lYW5zIHRvIHRlc3QgZm9yIGRpZmZlcmVuY2VzIGJldHdlZW4gdGltZXBoYXNlcyB3aXRoaW4gZ3JvdXBzIGFuZCBncm91cHMgd2l0aGluIHRpbWVwaGFzZSBhbmQgCgpgYGB7cn0KbGlicmFyeShlbW1lYW5zKQoKZW1tX3gxYSA9IGVtbWVhbnMobW9kX3hfMiwgc3BlY3MgPSBwYWlyd2lzZSB+IFRpbWVQaGFzZXxSb2xlLCB3ZWlnaHRzID0gInByb3BvcnRpb25hbCIpICN0aW1lcGhhc2VzIHcvbiBncm91cHMKZW1tX3gxYSA9IGFzX3RpYmJsZShlbW1feDFhJGNvbnRyYXN0cykKCmVtbV94MiA9IGVtbWVhbnMobW9kX3hfMiwgc3BlY3MgPSBwYWlyd2lzZSB+IFJvbGV8VGltZVBoYXNlLCB3ZWlnaHRzID0gInByb3BvcnRpb25hbCIpICNncm91cHMgdy9uIHRpbWVwaGFzZXMKZW1tX3gyID0gYXNfdGliYmxlKGVtbV94MiRjb250cmFzdHMpCgojc2VlIGhlcmU6IGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9lbW1lYW5zL3ZpZ25ldHRlcy9pbnRlcmFjdGlvbnMuaHRtbAoKZW1tX3gxYSAlPiUgZmlsdGVyKHAudmFsdWUgPCAwLjA1KQplbW1feDIgJT4lIGZpbHRlcihwLnZhbHVlIDwgMC4wNSkKCmBgYApTZXZlcmFsIGNvbnRyYXN0cyBhcmUgc2lnbmlmaWNhbnQuIExldCdzIGNhbGN1bGF0ZSB0aGUgZWZmZWN0IHNpemVzCmBgYHtyfQpjb2hlbnNkXzIgPSBmdW5jdGlvbihkaWZmXywgc2QxLCBzZDIpewogIGNkID0gZGlmZl8vKHNxcnQoKHNkMV4yICsgc2QyXjIpLzIpKQogIHJldHVybihjZCkKfQoKCnNkcy54ID0gcmVnX2RhdCAlPiUgZ3JvdXBfYnkoUm9sZSwgYXMuZmFjdG9yKFRpbWVQaGFzZSkpICU+JSBzdW1tYXJpc2Uoc3RkZXYgPSBzZChTVkQxKSkKCiN0aW1lcGhhc2VzIHcvbiBncm91cHMKZW5nX3QxdDIgPSBjb2hlbnNkXzIoZW1tX3gxYSRlc3RpbWF0ZVsxXSxzZDEgPSBzZHMueCRzdGRldlsxXSwgc2QyID0gc2RzLngkc3RkZXZbMl0pLiAjIyNGSVgKZW5nX3QxdDMgPSBjb2hlbnNkXzIoZW1tX3gxYSRlc3RpbWF0ZVsyXSxzZDEgPSBzZHMueCRzdGRldlsxXSwgc2QyID0gc2RzLngkc3RkZXZbM10pCnNkX3QxdDIgPSBjb2hlbnNkXzIoZW1tX3gxYSRlc3RpbWF0ZVszXSxzZDEgPSBzZHMueCRzdGRldls0XSwgc2QyID0gc2RzLngkc3RkZXZbNV0pCnNkX3QxdDMgPSBjb2hlbnNkXzIoZW1tX3gxYSRlc3RpbWF0ZVs0XSxzZDEgPSBzZHMueCRzdGRldls0XSwgc2QyID0gc2RzLngkc3RkZXZbNl0pCnBkX3QxdDMgPSBjb2hlbnNkXzIoZW1tX3gxYSRlc3RpbWF0ZVs1XSxzZDEgPSBzZHMueCRzdGRldls3XSwgc2QyID0gc2RzLngkc3RkZXZbOV0pCnBkX3QydDMgPSBjb2hlbnNkXzIoZW1tX3gxYSRlc3RpbWF0ZVs2XSxzZDEgPSBzZHMueCRzdGRldls4XSwgc2QyID0gc2RzLngkc3RkZXZbOV0pCgpwcmludChsaXN0KGVuZ190MXQyLGVuZ190MXQzLHNkX3QxdDMsc2RfdDF0MyxwZF90MXQzLHBkX3QydDMpKQoKCmBgYAoKTWFyZ2luYWwgbWVhbnMgLSB5IFJRMQoKYGBge3J9CmxpYnJhcnkoZW1tZWFucykKCmVtbV95MT0gZW1tZWFucyhtb2RfeV8yLCBzcGVjcyA9IHBhaXJ3aXNlIH4gUm9sZSwgd2VpZ2h0cyA9ICJwcm9wb3J0aW9uYWwiKQojcHJpbnQoZW1tX3kxJGVtbWVhbnMpCnByaW50KGVtbV95MSRjb250cmFzdHMpCmBgYAoKCk1hcmdpbmFsIG1lYW5zIC1ZIFJRMiAKYGBge3J9CmVtbV95MSA9IGVtbWVhbnMobW9kX3lfMiwgc3BlY3MgPSBwYWlyd2lzZSB+IFRpbWVQaGFzZXxSb2xlLCB3ZWlnaHRzID0gInByb3BvcnRpb25hbCIpCnByaW50KGVtbV95MSRjb250cmFzdHMpCgplbW1feTIgPSBlbW1lYW5zKG1vZF95XzIsIHNwZWNzID0gcGFpcndpc2UgfiBSb2xlfFRpbWVQaGFzZSwgd2VpZ2h0cyA9ICJwcm9wb3J0aW9uYWwiKQpwcmludChlbW1feTIkY29udHJhc3RzKQpgYGAKCkNhbGN1bGF0ZSBlZmYgc2l6ZXMKYGBge3J9CmxpYnJhcnkocHN5Y2gpCmBgYAoKTW9kZWwgZGlhZ25vc3RpY3MKCmBgYHtyfQojdG9kbwpsaWJyYXJ5KHBlcmZvcm1hbmNlKQpsaWJyYXJ5KHNlZSkKCmNoZWNrX21vZGVsKG1vZF94XzIpCmNoZWNrX21vZGVsKG1vZF95XzIpCmBgYAoKClBsb3QgbmV0d29yayBzdWJ0cmFjdGlvbnMgKHJlcGxhY2UgVGltZVBoYXNlIGFuZCBSb2xlIGZvciBkaWZmZXJlbnQgY29tYmluYXRpb25zKQpgYGB7cn0KbWVhbjEgPSBzZXRfMSRwb2ludHMgJT4lIGRwbHlyOjpmaWx0ZXIoVGltZVBoYXNlID09IDEsIFJvbGUgPT0gIkVuZ2luZWVyIikgI3VwZGF0ZSBoZXJlCm1lYW4yID0gc2V0XzEkcG9pbnRzICU+JSBkcGx5cjo6ZmlsdGVyKFRpbWVQaGFzZSA9PSAxLCBSb2xlID09ICJTZXJ2aWNlRGVzaWduZXIiKSAjdXBkYXRlIGhlcmUKCm1lYW4xX25ldCA9IHNldF8xJGxpbmUud2VpZ2h0cyAlPiUgZHBseXI6OmZpbHRlcihUaW1lUGhhc2UgPT0gMSwgUm9sZSA9PSAiRW5naW5lZXIiKSAlPiUgY29sTWVhbnMoKQptZWFuMl9uZXQgPSBzZXRfMSRsaW5lLndlaWdodHMgJT4lIGRwbHlyOjpmaWx0ZXIoVGltZVBoYXNlID09IDEsIFJvbGUgPT0gIlNlcnZpY2VEZXNpZ25lciIpICU+JSBjb2xNZWFucygpICN1cGRhdGUgaGVyZQoKcGxvdChzZXRfMSwgdGl0bGUgPSAiTmV0d29yayBzdWJ0cmFjdGlvbiIpIHw+CiAgdW5pdHMoCiAgICBwb2ludHMgPSBtZWFuMSwgCiAgICBwb2ludHNfY29sb3IgPSAicmVkIiwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogIHVuaXRzKAogICAgcG9pbnRzID0gbWVhbjIsIAogICAgcG9pbnRzX2NvbG9yID0gImJsdWUiLAogICAgc2hvd19tZWFuID0gVFJVRSwgc2hvd19wb2ludHMgPSBGQUxTRSwgd2l0aF9jaSA9IFRSVUUpIHw+CiAgZWRnZXMoCiAgICB3ZWlnaHRzID0gbWVhbjFfbmV0IC0gbWVhbjJfbmV0LCAjIG9wdGlvbmFsIG11bHRpcGxpZXIgdG8gYWRqdXN0IGZvciByZWFkYWJpbGl0eQogICAgZWRnZV9zaXplX211bHRpcGxpZXIgPSBlZGdlX3NpemVfbXVsdGlwbGllciwKICAgIGVkZ2VfYXJyb3dfc2F0dXJhdGlvbl9tdWx0aXBsaWVyID0gZWRnZV9hcnJvd19zYXR1cmF0aW9uX211bHRpcGxpZXIsCiAgICBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIgPSBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBlZGdlX2NvbG9yID0gYygicmVkIiwiYmx1ZSIpKSB8PgogIG5vZGVzKAogICAgbm9kZV9zaXplX211bHRpcGxpZXIgPSBub2RlX3NpemVfbXVsdGlwbGllciwKICAgIG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciA9IG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciwKICAgIHNlbGZfY29ubmVjdGlvbl9jb2xvciA9IGMoInJlZCIsImJsdWUiKSkKCgpgYGAKCk1vZGVsIDI6IEVwaXN0ZW1pYyBBZ2VuY3kgQ29kZXMKClBsb3QgMTogTWVhbiBOZXR3b3JrCgpgYGB7cn0Kbm9kZV9zaXplX211bHRpcGxpZXIgPSAwLjMgIyBzY2FsZSB1cCBvciBkb3duIG5vZGUgc2l6ZXMKbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyID0gMSAjIHpvb20gaW4gb3Igb3V0IG5vZGUgcG9zaXRpb25zCnBvaW50X3Bvc2l0aW9uX211bHRpcGxpZXIgPSAxICMgem9vbSBpbiBvciBvdXQgdGhlIHBvaW50IHBvc2l0aW9ucwplZGdlX2Fycm93X3NhdHVyYXRpb25fbXVsdGlwbGllciA9IDEuNSAjIGFkanVzdCB0aGUgY2hldnJvbiBjb2xvciBsaWdodGVyIG9yIGRhcmtlcgplZGdlX3NpemVfbXVsdGlwbGllciA9IDIgIyBzY2FsZSB1cCBvciBkb3duIGVkZ2Ugc2l6ZXMKYGBgCgoKYGBge3J9CnBsb3Qoc2V0XzIsIHRpdGxlID0gIk92ZXJhbGwgTWVhbi0tQWdlbmN5IikgfD4KICB1bml0cygKICAgIHBvaW50cz0gc2V0XzIkcG9pbnRzLCAKICAgIHBvaW50X3Bvc2l0aW9uX211bHRpcGxpZXIgPSBwb2ludF9wb3NpdGlvbl9tdWx0aXBsaWVyLAogICAgcG9pbnRzX2NvbG9yID0gYygiYmxhY2siKSwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gVFJVRSwgd2l0aF9jaSA9IFRSVUUpIHw+CiAgZWRnZXMoCiAgICB3ZWlnaHRzID1zZXRfMiRsaW5lLndlaWdodHMsCiAgICBlZGdlX3NpemVfbXVsdGlwbGllciA9IGVkZ2Vfc2l6ZV9tdWx0aXBsaWVyLAogICAgZWRnZV9hcnJvd19zYXR1cmF0aW9uX211bHRpcGxpZXIgPSBlZGdlX2Fycm93X3NhdHVyYXRpb25fbXVsdGlwbGllciwKICAgIG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciA9IG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciwKICAgIGVkZ2VfY29sb3IgPSBjKCJibGFjayIpKSB8PgogIG5vZGVzKAogICAgbm9kZV9zaXplX211bHRpcGxpZXIgPSBub2RlX3NpemVfbXVsdGlwbGllciwKICAgIG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciA9IG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciwKICAgIG5vZGVfbGFiZWxzID0gVFJVRSwgIyBjaGFuZ2UgdGhpcyB0byBGQUxTRSBjYW4gcmVtb3ZlIG5vZGUgbGFiZWxzIGluIGNhc2UgeW91IHdhbnQgdG8gYWRkIHRoZW0gYmFjayBpbiBhIG5pY2VyIGZvbnQgb3Igc2l6ZSBmb3IgeW91ciBwcmVzZW50YXRpb25zIG9yIHB1YmxpY2F0aW9ucwogICAgc2VsZl9jb25uZWN0aW9uX2NvbG9yID0gYygiYmxhY2siKSkKYGBgCgpQbG90IDFiOiBPdmVyYWxsIEdyb3VwIENvbXBhcmlzb25zCmBgYHtyfQpwbG90KHNldF8yLCB0aXRsZSA9ICJHcm91cHMiKSB8PgogIHVuaXRzKAogICAgcG9pbnRzPSBzZXRfMiRwb2ludHMkUm9sZSRQcm9kdWN0RGVzaWduZXIsIAogICAgcG9pbnRfcG9zaXRpb25fbXVsdGlwbGllciA9IHBvaW50X3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBwb2ludHNfY29sb3IgPSBjKCJyZWQiKSwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogICB1bml0cygKICAgIHBvaW50cz0gc2V0XzIkcG9pbnRzJFJvbGUkRW5naW5lZXIsIAogICAgcG9pbnRfcG9zaXRpb25fbXVsdGlwbGllciA9IHBvaW50X3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBwb2ludHNfY29sb3IgPSBjKCJibHVlIiksCiAgICBzaG93X21lYW4gPSBUUlVFLCBzaG93X3BvaW50cyA9IEZBTFNFLCB3aXRoX2NpID0gVFJVRSkgfD4KICAgdW5pdHMoCiAgICBwb2ludHM9IHNldF8yJHBvaW50cyRSb2xlJFNlcnZpY2VEZXNpZ25lciwgCiAgICBwb2ludF9wb3NpdGlvbl9tdWx0aXBsaWVyID0gcG9pbnRfcG9zaXRpb25fbXVsdGlwbGllciwKICAgIHBvaW50c19jb2xvciA9IGMoImdyZWVuIiksCiAgICBzaG93X21lYW4gPSBUUlVFLCBzaG93X3BvaW50cyA9IEZBTFNFLCB3aXRoX2NpID0gVFJVRSkgfD4KICBub2Rlcyhub2RlX3NpemVfbXVsdGlwbGllciA9IDAuMywKICAgICAgICAgICAgbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyID0gbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyLAogICAgICAgICAgICBzZWxmX2Nvbm5lY3Rpb25fY29sb3IgPSBjKCJibGFjayIpKXw+CiAgICAgIHBsb3RseTo6bGF5b3V0KHNob3dsZWdlbmQgPSBUUlVFLCBsZWdlbmQgPSBsaXN0KHggPSAxMDAsIHkgPSAwLjkpKSB8PgogICAgICBwbG90bHk6OnN0eWxlKG5hbWUgPSAiUHJvZHVjdCBEZXNpZ25lciIsIHRyYWNlcyA9IHRyYWNlc1sxXSkgfD4KICAgICAgcGxvdGx5OjpzdHlsZShuYW1lID0gIkVuZ2luZWVyIiwgdHJhY2VzID0gdHJhY2VzWzJdKSB8PgogICAgICBwbG90bHk6OnN0eWxlKG5hbWUgPSAiU2VydmljZSBEZXNpZ25lciIsIHRyYWNlcyA9IHRyYWNlc1szXSkKICAKYGBgClBsb3QgMWM6IEdyb3VwIHN1YnRyYWN0aW9ucwpgYGB7cn0KcHJvZF9wdHMgPSBzZXRfMiRwb2ludHMkUm9sZSRQcm9kdWN0RGVzaWduZXIgCmVuZ19wdHMgPSBzZXRfMiRwb2ludHMkUm9sZSRFbmdpbmVlcgpzZXJ2X3B0cyA9IHNldF8yJHBvaW50cyRSb2xlJFNlcnZpY2VEZXNpZ25lcgoKcHJvZF9tZWFuX25ldCA9IHNldF8yJGxpbmUud2VpZ2h0cyAlPiUgZHBseXI6OmZpbHRlcihSb2xlID09ICJQcm9kdWN0RGVzaWduZXIiKSAlPiUgY29sTWVhbnMoKQplbmdfbWVhbl9uZXQgPSBzZXRfMiRsaW5lLndlaWdodHMgJT4lIGRwbHlyOjpmaWx0ZXIoUm9sZSA9PSAiRW5naW5lZXIiKSAlPiUgY29sTWVhbnMoKQpzZXJ2X21lYW5fbmV0ID0gc2V0XzIkbGluZS53ZWlnaHRzICU+JSBkcGx5cjo6ZmlsdGVyKFJvbGUgPT0gIlNlcnZpY2VEZXNpZ25lciIpICU+JSBjb2xNZWFucygpCgpwbG90KHNldF8yLCB0aXRsZSA9ICJQcm9kdWN0IERlc2lnbmVyIHZzIEVuZ2luZWVyIikgfD4KICB1bml0cygKICAgIHBvaW50cyA9IHByb2RfcHRzLCAKICAgIHBvaW50c19jb2xvciA9ICJyZWQiLAogICAgc2hvd19tZWFuID0gVFJVRSwgc2hvd19wb2ludHMgPSBGQUxTRSwgd2l0aF9jaSA9IFRSVUUpIHw+CiAgdW5pdHMoCiAgICBwb2ludHMgPSBlbmdfcHRzLCAKICAgIHBvaW50c19jb2xvciA9ICJibHVlIiwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogIGVkZ2VzKAogICAgd2VpZ2h0cyA9IHByb2RfbWVhbl9uZXQgLSBlbmdfbWVhbl9uZXQsICMgb3B0aW9uYWwgbXVsdGlwbGllciB0byBhZGp1c3QgZm9yIHJlYWRhYmlsaXR5CiAgICBlZGdlX3NpemVfbXVsdGlwbGllciA9IGVkZ2Vfc2l6ZV9tdWx0aXBsaWVyLAogICAgZWRnZV9hcnJvd19zYXR1cmF0aW9uX211bHRpcGxpZXIgPSBlZGdlX2Fycm93X3NhdHVyYXRpb25fbXVsdGlwbGllciwKICAgIG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciA9IG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciwKICAgIGVkZ2VfY29sb3IgPSBjKCJyZWQiLCJibHVlIikpIHw+CiAgbm9kZXMoCiAgICBub2RlX3NpemVfbXVsdGlwbGllciA9IG5vZGVfc2l6ZV9tdWx0aXBsaWVyLAogICAgbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyID0gbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyLAogICAgc2VsZl9jb25uZWN0aW9uX2NvbG9yID0gYygicmVkIiwiYmx1ZSIpKQoKcGxvdChzZXRfMiwgdGl0bGUgPSAiUHJvZHVjdCBEZXNpZ25lciB2cyBTZXJ2aWNlRGVzaWduZXIiKSB8PgogIHVuaXRzKAogICAgcG9pbnRzID0gcHJvZF9wdHMsIAogICAgcG9pbnRzX2NvbG9yID0gInJlZCIsCiAgICBzaG93X21lYW4gPSBUUlVFLCBzaG93X3BvaW50cyA9IEZBTFNFLCB3aXRoX2NpID0gVFJVRSkgfD4KICB1bml0cygKICAgIHBvaW50cyA9c2Vydl9wdHMsIAogICAgcG9pbnRzX2NvbG9yID0gImdyZWVuIiwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogIGVkZ2VzKAogICAgd2VpZ2h0cyA9IHByb2RfbWVhbl9uZXQgLSBzZXJ2X21lYW5fbmV0LCAjIG9wdGlvbmFsIG11bHRpcGxpZXIgdG8gYWRqdXN0IGZvciByZWFkYWJpbGl0eQogICAgZWRnZV9zaXplX211bHRpcGxpZXIgPSBlZGdlX3NpemVfbXVsdGlwbGllciwKICAgIGVkZ2VfYXJyb3dfc2F0dXJhdGlvbl9tdWx0aXBsaWVyID0gZWRnZV9hcnJvd19zYXR1cmF0aW9uX211bHRpcGxpZXIsCiAgICBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIgPSBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBlZGdlX2NvbG9yID0gYygicmVkIiwiZ3JlZW4iKSkgfD4KICBub2RlcygKICAgIG5vZGVfc2l6ZV9tdWx0aXBsaWVyID0gbm9kZV9zaXplX211bHRpcGxpZXIsCiAgICBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIgPSBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBzZWxmX2Nvbm5lY3Rpb25fY29sb3IgPSBjKCJyZWQiLCJncmVlbiIpKQoKcGxvdChzZXRfMiwgdGl0bGUgPSAiU2VydmljZSBEZXNpZ25lciB2cyBFbmdpbmVlciIpIHw+CiAgdW5pdHMoCiAgICBwb2ludHMgPSBzZXJ2X3B0cywgCiAgICBwb2ludHNfY29sb3IgPSAiZ3JlZW4iLAogICAgc2hvd19tZWFuID0gVFJVRSwgc2hvd19wb2ludHMgPSBGQUxTRSwgd2l0aF9jaSA9IFRSVUUpIHw+CiAgdW5pdHMoCiAgICBwb2ludHMgPSBlbmdfcHRzLCAKICAgIHBvaW50c19jb2xvciA9ICJibHVlIiwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogIGVkZ2VzKAogICAgd2VpZ2h0cyA9IHNlcnZfbWVhbl9uZXQgLSBlbmdfbWVhbl9uZXQsICMgb3B0aW9uYWwgbXVsdGlwbGllciB0byBhZGp1c3QgZm9yIHJlYWRhYmlsaXR5CiAgICBlZGdlX3NpemVfbXVsdGlwbGllciA9IDEsCiAgICBlZGdlX2Fycm93X3NhdHVyYXRpb25fbXVsdGlwbGllciA9IGVkZ2VfYXJyb3dfc2F0dXJhdGlvbl9tdWx0aXBsaWVyLAogICAgbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyID0gbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyLAogICAgZWRnZV9jb2xvciA9IGMoImdyZWVuIiwiYmx1ZSIpKSB8PgogIG5vZGVzKAogICAgbm9kZV9zaXplX211bHRpcGxpZXIgPSBub2RlX3NpemVfbXVsdGlwbGllciwKICAgIG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciA9IG5vZGVfcG9zaXRpb25fbXVsdGlwbGllciwKICAgIHNlbGZfY29ubmVjdGlvbl9jb2xvciA9IGMoImdyZWVuIiwiYmx1ZSIpKQpgYGAKClBsb3QgMjogQWxsIE1lYW5zCmBgYHtyfQoKI2dldCBsaXN0IG9mIHRpbWUgcGhhc2VzIGFuZCBncm91cHMgbG9vcCBvdmVyIG9yIHVzZSBtYXAgZnVuY3Rpb24KCnBoYXNlcyA9IHVuaXF1ZShzZXRfMiRwb2ludHMkVGltZVBoYXNlKQoKZ3JvdXBzID0gdW5pcXVlKHNldF8yJHBvaW50cyRSb2xlKQoKCmNvbF9saXN0XzIgPSBjKCJyZWQiLAogICAgICAgICAgICAgICJibHVlIiwKICAgICAgICAgICAgICAiZ3JlZW4iKQoKdHJhY2VzID0gYygyOjEwKQoKeF9hZ2VuY3kgPSBwbG90KHNldF8yLCB0aXRsZSA9ICJHcm91cCBNZWFucyBieSBQaGFzZSAtLSBBZ2VuY3kiKQpjb3VudCA9IDEKCmZvciAoaSBpbiAxOmxlbmd0aChwaGFzZXMpKXsKICBmb3IgKGogaW4gMTpsZW5ndGgoZ3JvdXBzKSl7CiAgICBwb2ludHMgPSBzZXRfMiRwb2ludHMgJT4lIGZpbHRlcihUaW1lUGhhc2UgPT0gcGhhc2VzW2ldLCBSb2xlID09IGdyb3Vwc1tqXSkKICAgICNwcmludChoZWFkKHBvaW50cykpCiAgICB4X2FnZW5jeSA9IHhfYWdlbmN5IHw+CiAgICAgIHVuaXRzKAogICAgICAgIHBvaW50cyA9IHBvaW50cywKICAgICAgICBwb2ludF9wb3NpdGlvbl9tdWx0aXBsaWVyID0gcG9pbnRfcG9zaXRpb25fbXVsdGlwbGllciwKICAgICAgICBwb2ludHNfY29sb3IgPSBjb2xfbGlzdF8yW2ldLAogICAgICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRiwgd2l0aF9jaSA9IEZBTFNFCiAgICAgICAgKSB8PgogICAgICBub2Rlcyhub2RlX3NpemVfbXVsdGlwbGllciA9IDAuMywKICAgICAgICAgICAgbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyID0gbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyLAogICAgICAgICAgICBzZWxmX2Nvbm5lY3Rpb25fY29sb3IgPSBjKCJibGFjayIpKXw+CiAgICAgIHBsb3RseTo6bGF5b3V0KHNob3dsZWdlbmQgPSBUUlVFLCBsZWdlbmQgPSBsaXN0KHggPSAxMDAsIHkgPSAwLjkpKSB8PgogICAgICBwbG90bHk6OnN0eWxlKG5hbWUgPSBwYXN0ZTAocGhhc2VzW2ldLCIgLSAiLGdyb3Vwc1tqXSksIHRyYWNlcyA9IHRyYWNlc1tjb3VudF0pCiAgICBjb3VudCA9IGNvdW50ICsgMQogICAgCiAgfQp9Cgp4X2FnZW5jeQpgYGAKCkNoZWNrIG5lc3RpbmcKCmBgYHtyfQpyZWdfZGF0X2FnZW5jeSA9IHNldF8yJHBvaW50cyAlPiUgZmlsdGVyKEVOQV9ESVJFQ1RJT04gPT0gInJlc3BvbnNlIikKCklDQzo6SUNDZXN0KFNwZWFrZXIsU1ZEMSxyZWdfZGF0X2FnZW5jeSkgI25vdCBzaWduaWZpY2FudAoKSUNDOjpJQ0Nlc3QoU3BlYWtlcixTVkQyLHJlZ19kYXRfYWdlbmN5KSAjc2lnbmlmaWNhbnQgd2Ugd2lsbCBuZWVkIHRvIGluY2x1ZGUgYSB2YXJpYWJsZSBmb3IgaW5kaXZpZHVhbCBpbiB0aGUgbW9kZWwKYGBgCgoKYGBge3J9Cm1vZF94X2FnZW5jeSA9IGxtKFNWRDEgfiBhcy5mYWN0b3IoVGltZVBoYXNlKSArIFJvbGUsIGRhdGEgPSByZWdfZGF0X2FnZW5jeSkKbW9kX3lfYWdlbmN5ID0gbG0oU1ZEMiB+IGFzLmZhY3RvcihUaW1lUGhhc2UpICsgUm9sZSwgZGF0YSA9IHJlZ19kYXRfYWdlbmN5KQoKCnN1bW1hcnkobW9kX3hfYWdlbmN5KQpzdW1tYXJ5KG1vZF95X2FnZW5jeSkKYGBgCgpjaGVjayBmb3IgaW50ZXJhY3Rpb25zOiAoaW50ZXJhY3Rpb25zIGFyZSBzaWduaWZpY2FudCBzbyB3ZSBzaG91bGQgdXNlIHRob3NlIG1vZGVzKQpgYGB7cn0KbW9kX3hfYWdlbmN5XzIgPSBsbShTVkQxIH4gYXMuZmFjdG9yKFRpbWVQaGFzZSkgKyBSb2xlICsgYXMuZmFjdG9yKFRpbWVQaGFzZSkqUm9sZSwgZGF0YSA9IHJlZ19kYXRfYWdlbmN5KQptb2RfeV9hZ2VuY3lfMiA9IGxtKFNWRDIgfiBhcy5mYWN0b3IoVGltZVBoYXNlKSArIFJvbGUgKyBhcy5mYWN0b3IoVGltZVBoYXNlKSpSb2xlLCBkYXRhID0gcmVnX2RhdF9hZ2VuY3kpCgpzdW1tYXJ5KG1vZF94X2FnZW5jeV8yKQpzdW1tYXJ5KG1vZF95X2FnZW5jeV8yKQoKYW5vdmEobW9kX3hfYWdlbmN5LG1vZF94X2FnZW5jeV8yKQphbm92YShtb2RfeV9hZ2VuY3ksbW9kX3lfYWdlbmN5XzIpCgpgYGAKCiNOZWVkIHRvIHJ1biBtaXhlZCBtb2RlbCBmb3IgWQojI21vZGVsIGlzIHNpbmd1bGFyIHNvIHN0aWNrIHdpdGggT0xTCgpgYGB7cn0KbGlicmFyeShsbWVyVGVzdCkKCm1vZF95X2FnZW5jeV9taXhlZCA9IGxtZXJUZXN0OjpsbWVyKFNWRDIgfiAxICsgKDF8U3BlYWtlcikgKyBhcy5mYWN0b3IoVGltZVBoYXNlKSpSb2xlICxkYXRhID0gcmVnX2RhdF9hZ2VuY3kpCgpzdW1tYXJ5KG1vZF95X2FnZW5jeV9taXhlZCkKYGBgCgoKCk1hcmdpbmFsIG1lYW5zIHggLSBSUTEKYGBge3J9CmVtbV9hZzEgPSBlbW1lYW5zKG1vZF94X2FnZW5jeV8yLCBzcGVjcyA9IHBhaXJ3aXNlIH4gUm9sZSwgd2VpZ2h0cyA9ICJwcm9wb3J0aW9uYWwiKQpwcmludChlbW1fYWcxJGVtbWVhbnMpCnByaW50KGVtbV9hZzEkY29udHJhc3RzKQpgYGAKClZpZXdpbmcgaW50ZXJhY3Rpb25zCmBgYHtyfQplbW1pcChtb2RfeF9hZ2VuY3lfMiwgUm9sZSB+IFRpbWVQaGFzZSkKCmBgYAoKCk1hcmdpbmFsIG1lYW5zIC0geCBSUTIKYGBge3J9CmVtbV9hZzEgPSBlbW1lYW5zKG1vZF94X2FnZW5jeV8yLCBzcGVjcyA9IHBhaXJ3aXNlIH4gVGltZVBoYXNlfFJvbGUsIHdlaWdodHMgPSAicHJvcG9ydGlvbmFsIikKZW1tX2FnMSRjb250cmFzdHMKCmVtbV9hZzIgPSBlbW1lYW5zKG1vZF94X2FnZW5jeV8yLCBzcGVjcyA9IHBhaXJ3aXNlIH4gUm9sZXxUaW1lUGhhc2UsIHdlaWdodHMgPSAicHJvcG9ydGlvbmFsIikKZW1tX2FnMiRjb250cmFzdHMKCmBgYApNYXJnaW5hbCBtZWFucyB5IC0gUlExCmBgYHtyfQplbW1fYWdfeTEgPSBlbW1lYW5zKG1vZF95X2FnZW5jeV8yLCBzcGVjcyA9IHBhaXJ3aXNlIH4gUm9sZSwgd2VpZ2h0cyA9ICJwcm9wb3J0aW9uYWwiKQpwcmludChlbW1fYWdfeTEkZW1tZWFucykKcHJpbnQoZW1tX2FnX3kxJGNvbnRyYXN0cykKYGBgCgpWaWV3aW5nIGludGVyYWN0aW9ucwpgYGB7cn0KZW1taXAobW9kX3lfYWdlbmN5XzIsIFJvbGUgfiBUaW1lUGhhc2UpCmBgYAoKTWFyZ2luYWwgbWVhbnMgLSB5IFJRMgpgYGB7cn0KZW1tX2FnX3kxID0gZW1tZWFucyhtb2RfeV9hZ2VuY3lfMiwgc3BlY3MgPSBwYWlyd2lzZSB+IFRpbWVQaGFzZXxSb2xlLCB3ZWlnaHRzID0gInByb3BvcnRpb25hbCIpCmVtbV9hZ195MSRjb250cmFzdHMKCmVtbV9hZ195MiA9IGVtbWVhbnMobW9kX3lfYWdlbmN5XzIsIHNwZWNzID0gcGFpcndpc2UgfiBSb2xlfFRpbWVQaGFzZSwgd2VpZ2h0cyA9ICJwcm9wb3J0aW9uYWwiKQplbW1fYWdfeTIkY29udHJhc3RzCmBgYAoKQ2FsY3VsYXRlIGVmZiBzaXplcwpgYGB7cn0KI3RvIGRvCmBgYAoKCk1vZGVsIGRpYWdub3N0aWNzCmBgYHtyfQpjaGVja19tb2RlbChtb2RfeF9hZ2VuY3lfMikKY2hlY2tfbW9kZWwobW9kX3lfYWdlbmN5XzIpCmBgYAoKClBsb3QgbmV0d29yayBzdWJ0cmFjdGlvbnMKYGBge3J9Cm1lYW4xID0gc2V0XzIkcG9pbnRzICU+JSBkcGx5cjo6ZmlsdGVyKFRpbWVQaGFzZSA9PSAxLCBSb2xlID09ICJFbmdpbmVlciIpCm1lYW4yID0gc2V0XzIkcG9pbnRzICU+JSBkcGx5cjo6ZmlsdGVyKFRpbWVQaGFzZSA9PSAxLCBSb2xlID09ICJQcm9kdWN0RGVzaWduZXIiKQoKbWVhbjFfbmV0ID0gc2V0XzIkbGluZS53ZWlnaHRzICU+JSBkcGx5cjo6ZmlsdGVyKFRpbWVQaGFzZSA9PSAxLCBSb2xlID09ICJFbmdpbmVlciIpICU+JSBjb2xNZWFucygpCm1lYW4yX25ldCA9IHNldF8yJGxpbmUud2VpZ2h0cyAlPiUgZHBseXI6OmZpbHRlcihUaW1lUGhhc2UgPT0gMSwgUm9sZSA9PSAiUHJvZHVjdERlc2lnbmVyIikgJT4lIGNvbE1lYW5zKCkKCnBsb3Qoc2V0XzIsIHRpdGxlID0gIk5ldHdvcmsgc3VidHJhY3Rpb24iKSB8PgogIHVuaXRzKAogICAgcG9pbnRzID0gbWVhbjEsIAogICAgcG9pbnRzX2NvbG9yID0gInJlZCIsCiAgICBzaG93X21lYW4gPSBUUlVFLCBzaG93X3BvaW50cyA9IEZBTFNFLCB3aXRoX2NpID0gVFJVRSkgfD4KICB1bml0cygKICAgIHBvaW50cyA9IG1lYW4yLCAKICAgIHBvaW50c19jb2xvciA9ICJibHVlIiwKICAgIHNob3dfbWVhbiA9IFRSVUUsIHNob3dfcG9pbnRzID0gRkFMU0UsIHdpdGhfY2kgPSBUUlVFKSB8PgogIGVkZ2VzKAogICAgd2VpZ2h0cyA9IG1lYW4xX25ldCAtIG1lYW4yX25ldCwgIyBvcHRpb25hbCBtdWx0aXBsaWVyIHRvIGFkanVzdCBmb3IgcmVhZGFiaWxpdHkKICAgIGVkZ2Vfc2l6ZV9tdWx0aXBsaWVyID0gZWRnZV9zaXplX211bHRpcGxpZXIsCiAgICBlZGdlX2Fycm93X3NhdHVyYXRpb25fbXVsdGlwbGllciA9IGVkZ2VfYXJyb3dfc2F0dXJhdGlvbl9tdWx0aXBsaWVyLAogICAgbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyID0gbm9kZV9wb3NpdGlvbl9tdWx0aXBsaWVyLAogICAgZWRnZV9jb2xvciA9IGMoInJlZCIsImJsdWUiKSkgfD4KICBub2RlcygKICAgIG5vZGVfc2l6ZV9tdWx0aXBsaWVyID0gbm9kZV9zaXplX211bHRpcGxpZXIsCiAgICBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIgPSBub2RlX3Bvc2l0aW9uX211bHRpcGxpZXIsCiAgICBzZWxmX2Nvbm5lY3Rpb25fY29sb3IgPSBjKCJyZWQiLCJibHVlIikpCmBgYAoKCg==